[−][src]Crate tang_rs
A connection pool running one tokio runtime.
Known Limitation:
No tests. can't be used in nested runtimes.
Example:
ⓘThis example is not tested
use std::time::Duration; use futures_util::TryStreamExt; use tokio_postgres_tang::{Builder, PostgresPoolError, PostgresManager}; #[tokio::main] async fn main() -> std::io::Result<()> { let db_url = "postgres://postgres:123@localhost/test"; // setup manager let mgr = PostgresManager::new_from_stringlike( db_url, tokio_postgres::NoTls, ).unwrap_or_else(|_| panic!("can't make postgres manager")); //make prepared statements to speed up frequent used queries. It just stores your statement info in a hash map and //you can skip this step if you don't need any prepared statement. let mgr = mgr // alias is used to call according statement later. // pass &[tokio_postgres::types::Type] if you want typed statement. pass &[] for no typed statement. .prepare_statement("get_topics", "SELECT * FROM topics WHERE id=ANY($1)", &[tokio_postgres::types::Type::OID_ARRAY]) .prepare_statement("get_users", "SELECT * FROM posts WHERE id=ANY($1)", &[]); // make pool let pool = Builder::new() .always_check(false) // if set true every connection will be checked before checkout. .idle_timeout(None) // set idle_timeout and max_lifetime both to None to ignore idle connection drop. .max_lifetime(Some(Duration::from_secs(30 * 60))) .connection_timeout(Duration::from_secs(5)) // set the timeout when connection to database(used when establish new connection and doing always_check). .wait_timeout(Duration::from_secs(5)) // set the timeout when waiting for a connection. .min_idle(1) .max_size(12) .build(mgr) .await .unwrap_or_else(|_| panic!("can't make pool")); // wait a bit as the pool spawn connections asynchronously tokio::timer::delay(std::time::Instant::now() + std::time::Duration::from_secs(1)).await; // get a pool ref let pool_ref = pool.get().await.expect("can't get pool ref"); // deref or derefmut to get connection. let (client, statements) = &*pool_ref; /* It's possible to insert new statement into statements from pool_ref. But be ware the statement will only work on this specific connection and not other connections in the pool. The additional statement will be dropped when the connection is dropped from pool. A newly spawned connection will not include this additional statement. * This newly inserted statement most likely can't take advantage of the pipeline query features as we didn't join futures when prepare this statement. * It's suggested that if you want pipelined statements you should join the futures of prepare before calling await on them. There is tang_rs::CacheStatement trait for PoolRef<PostgresManager<T>> to help you streamline this operation. */ // use the alias input when building manager to get specific statement. let statement = statements.get("get_topics").unwrap(); let rows = client.query(statement, &[]).await.expect("Query failed"); // drop the pool ref to return connection to pool drop(pool_ref); // run the pool and use closure to query the pool. let _rows = pool .run(|mut conn| Box::pin( // pin the async function to make sure the &mut Conn outlives our closure. async move { let (client, statements) = &conn; let statement = statements.get("get_topics").unwrap(); let rows = client.query(statement, &[]).await?; // default error type. // you can infer your own error type as long as it impl From trait for tang_rs::PostgresPoolError Ok::<_, PostgresPoolError>(rows) } )) .await .map_err(|e| { match e { PostgresPoolError::Inner(e) => println!("{:?}", e), PostgresPoolError::TimeOut => () }; std::io::Error::new(std::io::ErrorKind::Other, "place holder error") })?; Ok(()) }
Structs
Builder | |
Conn | |
IdleConn | |
Pool | |
PoolRef | |
TokioTimeElapsed | Error returned by |
Traits
Manager | trait come from bb8. |
Functions
tokio_spawn | Spawns a new asynchronous task, returning a
|
Type Definitions
ManagerFuture |